home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0992.ARJ / DBCMD.ASM < prev    next >
Assembly Source File  |  1992-07-03  |  79KB  |  1,743 lines

  1. ;dbcmd.asm 
  2. ;Debugger command processing routines
  3. ;
  4. .386P
  5. ;---------------------------------------------------------------------------- 
  6. ;Copyright 1991, 1992 ASMicro Co. 
  7. ;7/6/91       Rick Knoblaugh
  8. ;-----------------------------------------------------------------------------
  9.                 include dbequ.inc
  10.                 include dbstruc.inc
  11.                 include dbdat.inc
  12.  
  13. zcode    segment para public 'code16' use16
  14.                 extrn   ck_exec_bp:near, scroll_cmds_up:near, skip_white_sp:near
  15.                 extrn   convert_upper:near, prt_err_msg:near, get_validate:near
  16.                 extrn   clear_buffer:near, must_be_hex:near, editor:near
  17.                 extrn   put_hex_byte:near, put_nibble:near, format_seg:near
  18.                 extrn   do_left:near, do_right:near, do_rub_out:near
  19.                 extrn   do_insert:near, do_delete:near, put_hex_word:near
  20.                 extrn   xudflag:byte, xud_ip:word, xud_cs:word, xud_int:byte
  21.                 extrn   convert_2_linear:near
  22.  
  23.                 public  do_the_cmd, set_trap, show_regs, reset_trap
  24.                 public  do_bpint
  25.  
  26.     assume cs:zcode, ds:data, es:nothing
  27.  
  28. ;----------------------------------------------------------------------
  29. ; do_the_cmd - parse command strings and dispatch to appropriate      |
  30. ;              command processing routines.                           |
  31. ;                                                                     |
  32. ;             Enter: si = offset of start of cmd                      |
  33. ;                    cx = max chars entered - any leading white space |
  34. ;                                                                     |
  35. ;              Exit: carry flag set if we are to stay in debugger.    |
  36. ;                                                                     |
  37. ;----------------------------------------------------------------------
  38. do_the_cmd      proc    near
  39.                 call    scroll_cmds_up
  40.                 push    cx
  41.                 call    convert_upper
  42.                 mov     bx, offset cmd_table
  43.                 mov     ax, size cmd_info
  44.                 mov     cx, CMD_TABLE_LEN
  45.                 call    str_lookup
  46.                 or      cx, cx                  ;entire table searched?
  47.                 pop     cx                      ;restore count chars
  48.                 jnz     short do_the_c200       ;if command found
  49.                 mov     si, offset syntax_msg
  50.                 call    prt_err_msg             ;print msg and set carry 
  51.                 ret
  52. do_the_c200:
  53.  
  54. ;subtract cmd length from total characters entered
  55.                 sub     cl, [bx].cmd_len        
  56.                 call    [bx].cmd_routine        ;perform cmd processing
  57. do_the_c999:
  58.  
  59.                 ret
  60. do_the_cmd      endp
  61.  
  62. ;----------------------------------------------------------------------
  63. ; str_lookup - Perform table lookup for a text string.                |
  64. ;                                                                     |
  65. ;             Enter: si = offset of string on which to match          |
  66. ;                    ax = amount by which to increment table index    |
  67. ;                         May be called for use with tables where     |
  68. ;                         first two elements are:  offset of text     |
  69. ;                         and text length.  Other elements may or     |
  70. ;                         may not be present after these two.         |
  71. ;                                                                     |
  72. ;                    bx = offset of lookup table                      |
  73. ;                    cx = number of items in table                    |
  74. ;                                                                     |
  75. ;             Exit:                                                   |
  76. ;                    cx = zero if a match not found                   |
  77. ;                    bx = offset of record in table where found       |
  78. ;                    si = just after end of string                    |
  79. ;                                                                     |
  80. ;         es, di, dx saved                                            |
  81. ;----------------------------------------------------------------------
  82. str_lookup      proc    near
  83.                 push    dx
  84.                 push    di
  85.                 push    es
  86.  
  87.                 push    ds
  88.                 pop     es
  89.  
  90.                 mov     dx, si                  ;save start of string
  91. str_look100:
  92.                 push    cx                      ;count of table items
  93.                 mov     di, [bx].cmd_text       ;get offset of string
  94.                 movzx   cx, [bx].cmd_len
  95.                 repe    cmpsb
  96.                 pop     cx
  97.                 jz      short str_look400
  98. str_look300:
  99.                 add     bx, ax                  ;inc by record size
  100.                 mov     si, dx                  ;get back start of string
  101.                 loop    str_look100
  102. str_look400:
  103.                 pop     es
  104.                 pop     di
  105.                 pop     dx
  106.                 ret
  107. str_lookup      endp
  108.  
  109. ;----------------------------------------------------------------------
  110. ; do_trace - process trace command.  Valid syntax is T [n].           |
  111. ;                                                                     |
  112. ;             Enter: si = offset of cmd buffer just after "T"         |
  113. ;                    cx = max chars entered - cmd length              |
  114. ;                                                                     |
  115. ;              Exit: if command was valid, trap flag is set in flags  |
  116. ;                    on user stack.  Carry clear indicating leave     |
  117. ;                    debugger cmd loop and ret to user code.          |
  118. ;                                                                     |
  119. ;              trace_count = number of times to trace                 |
  120. ;                                                                     |
  121. ;                    if count specified was invalid, error message    |
  122. ;                    is displayed and return with Carry set.          |
  123. ;                                                                     |
  124. ;----------------------------------------------------------------------
  125. do_trace        proc    near
  126.                 mov     ax, 1           ;default to 1 trace
  127.                 call    skip_white_sp
  128.                 jcxz    do_t100
  129.                 mov     dx, 4           ;get a max of 4 digits
  130.                 call    get_validate    ;return value in ax
  131.                 jc      short do_t050   ;if count invalid
  132.                 or      ax, ax
  133.                 jnz     short do_t100   ;it can't be zero
  134.  
  135. do_t050:
  136.                 mov     si, offset bad_trace_msg
  137.                 call    prt_err_msg             ;print msg and set carry 
  138.                 ret
  139. do_t100:
  140.                 mov     trace_count, ax
  141. ;Save address of instruction through which we will be tracing.  If it is a
  142. ;software interrupt instruction, the PL0 code will use this address to 
  143. ;determine that it should generate an int 1 as the first instruction of the
  144. ;ISR is entered (i.e. this facilitates stepping through the int).
  145.                 mov     ax, [bp].regs_ip       
  146.                 mov     tuser_ip, ax
  147.                 mov     ax, [bp].regs_cs 
  148.                 mov     tuser_cs, ax
  149.                 call    set_trap
  150.                 clc                     ;exit debugger
  151. do_t999:
  152.                 ret
  153. do_trace        endp
  154.  
  155. set_trap        proc    near
  156.                 bts     [bp].regs_f, trapf     ;set trap flag     
  157.                 ret
  158. set_trap        endp
  159.  
  160. reset_trap      proc    near
  161.                 btr     [bp].regs_f, trapf      ;reset trap flag     
  162.                 ret
  163. reset_trap      endp
  164.  
  165. do_go           proc    near
  166.                 call    skip_white_sp
  167.                 jcxz    do_g900                 ;just go, so go
  168.                 call    get_seg_off             ;go get go address
  169.                 jnc     short do_g100
  170.                 mov     si, offset bad_addrs_msg
  171.                 call    prt_err_msg             ;print msg and set carry 
  172.                 ret
  173. do_g100:
  174.                 cmp     seg_found, TRUE ;user specify a segment?
  175.                 je      short do_g200
  176.                 mov     dx, [bp].regs_cs        ;get user cs register
  177. do_g200:
  178. ;have go address in dx:bx
  179.                 call    convert_2_linear        ;dx:bx to linear in edx
  180.                 mov     ch, 1                   ;set debug register
  181.                 mov     al, DEB_DAT_LEN1        ;exec breaks use 1 byte length
  182.                 mov     ah, DEB_TYPE_EXEC
  183.                 sub     cl, cl                  ;debug reg zero for go use
  184.                 cli
  185. ;
  186. ;Get PL0 code to manipulate debug registers
  187. ;
  188.                 int     60h                     ;do_debug_reg
  189.  
  190. do_g900:
  191.                 clc                     ;leave debugger
  192. do_g999:
  193.                 ret
  194. do_go           endp
  195.  
  196. ;----------------------------------------------------------------------
  197. ; do_reg - process register command.                                  |
  198. ;                                                                     |
  199. ;             Enter: si = offset of cmd buffer just after "R"         |
  200. ;                    cx = max chars entered - cmd length              |
  201. ;                                                                     |
  202. ;              Exit: carry set indicating go prompt for next command. |
  203. ;                                                                     |
  204. ;----------------------------------------------------------------------
  205. do_reg          proc    near
  206.                 call    skip_white_sp
  207.                 or      cx, cx
  208.                 jnz     short do_r040         ;if more than 'r' entered
  209.  
  210. ;user simply entered 'r' (and nothing else)
  211.                 call    show_regs
  212.                 stc
  213.                 ret
  214. do_r040:
  215.  
  216. ;
  217. ;do processing for individual registers
  218. ;
  219.                 push    cx              ;save number of chars entered
  220.                 mov     cx, REGS_TABLE_ENTRIES  ;number of registers
  221.                 mov     bx, offset regs_info_start ;start of register info
  222.                 mov     ax, size regs_stab      ;size to inc when search
  223.                 call    str_lookup
  224.                 or      cx, cx                  ;found in table?
  225.                 pop     cx
  226.                 jnz     short do_r050
  227.                 mov     si, offset bad_reg_msg
  228.                 call    prt_err_msg             ;print msg and set carry 
  229.                 ret                  
  230.  
  231. do_r050:
  232.                 mov     si, [bx].regs_stack_off ;offset on stack for reg
  233.                 push    si                      ;save register offset
  234.                 mov     ax, [bp + si]           ;get register value
  235.  
  236. do_r100:
  237.                 movzx   cx, [bx].regs_text_len
  238.                 mov     si, [bx].regs_text_off
  239.                 push    si                      ;save offset description
  240.                 push    cx                      ;and length
  241.                 call    disp_reg_eq             ;display reg description
  242.                 cmp     [bx].regs_text_len, 1   ;was entry found flags?
  243.                 jne     short do_r200           ;if not, go do regular reg
  244.                 call    disp_reg_flags
  245.                 jmp     short do_r300
  246.  
  247. do_r200:
  248.                 call    disp_reg_val            ;display reg value
  249. do_r300:
  250.                 call    scroll_cmds_up          ;scroll a line
  251.                 pop     cx
  252.                 pop     si
  253.                 call    disp_reg_eq             ;display reg description
  254.  
  255.                 call    clear_buffer
  256.                 mov     si, offset cmd_buffer
  257.  
  258.                 cmp     [bx].regs_text_len, 1   ;doing flags reg?
  259.                 jne     short do_r350           ;if not, go do regular reg
  260.                 call    accept_flags            ;get flags values
  261.                 pop     si                      ;restore stack offset        
  262.                 jnc     short do_r700           ;go assign new flags
  263.                 ret                             ;if error or user escaped
  264. do_r350:
  265.                 mov     dx, 4                   ;max in dl, dh=zero
  266.                 xor     bx, bx                  ;char counter
  267.                 mov     get_out, bx             ;no "get out" key
  268.                 mov     ax, offset must_be_hex
  269.                 mov     edit_routine, ax        ;assign to ptr     
  270.                 call    editor
  271.                 pop     bx                      ;restore stack offset(was si)
  272.                 movzx   cx, dh                  ;max chars entered
  273.                 call    scroll_cmds_up
  274.                 jcxz    do_r999                 ;user simply pressed return
  275.                 cmp     al, ESC_KEY             ;user aborted?
  276.                 je      short do_r999
  277.                 call    convert_upper
  278.  
  279.                 mov     dx, 4                   ;get max of 4 digits
  280.  
  281. ;get_validate returns the binary value of data (it also validates which has
  282. ;already been done, but several other places in the debugger use it for
  283. ;both functions)
  284.  
  285.                 call    get_validate            ;return value in ax
  286.                 mov     si, bx                  ;stack offset 
  287. do_r700:
  288.                 mov     [bp + si], ax           ;put back on stack
  289. do_r999:
  290.                 stc
  291.                 ret
  292. do_reg          endp
  293.  
  294. ;----------------------------------------------------------------------
  295. ; accept_flags - user has been prompted to enter new flags register   |
  296. ;                values.  Now, get those values and set/reset the     |
  297. ;                appropriate flags bits.  If values are invalid,      |
  298. ;                display an error message.                            |
  299. ;                                                                     |
  300. ;             Enter: si = start of data buffer                        |
  301. ;                 es:di = destination in video buffer                 |
  302. ;                    ax = flags register value                        |
  303. ;                                                                     |
  304. ;              Exit: carry set if user presses esc or data invalid.   |
  305. ;                    ax = updated flags register value                |
  306. ;----------------------------------------------------------------------
  307. accept_flags    proc    near
  308.                 mov     dx, CMD_MAX_LEN         ;max in dl, dh=zero
  309.                 xor     bx, bx                  ;char counter
  310.                 mov     get_out, bx             ;no "get out" key
  311.                 mov     edit_routine, bx        ;no special edit
  312.                 push    ax                      ;save flags reg value
  313.                 call    editor
  314.                 call    scroll_cmds_up
  315.                 cmp     al, ESC_KEY
  316.                 pop     ax                      ;restore flags reg value
  317.                 je      short accept_f900
  318.                 movzx   cx, dh                  ;max chars entered
  319.                 jcxz    accept_f800             ;end of input (if any) 
  320.                 call    convert_upper
  321. accept_f100:
  322.                 call    skip_white_sp
  323.                 jcxz    accept_f800             ;end of input (if any) 
  324.                 push    cx              ;save number of chars entered
  325.                 mov     cx, FLAGS_TABLE_ENTRIES  ;number of possibilities
  326.                 mov     bx, offset flags_info_start
  327.                 push    ax                      ;save flags value
  328.                 mov     ax, size flags_tbl      ;size to inc when search
  329.                 call    str_lookup
  330.                 pop     ax                      ;restore flags value
  331.                 or      cx, cx                  ;found in table?
  332.                 pop     cx
  333.  
  334.                 jnz     short accept_f200       
  335.                 mov     si, offset bad_flags_msg
  336.                 call    prt_err_msg             ;print msg and set carry 
  337.                 ret                             
  338. accept_f200:
  339.                 sub     cl, [bx].flen           ;subtract length of flag text
  340.                 mov     dl, [bx].fbit           ;get bit number
  341.                 sub     dh, dh
  342.                 bts     ax, dx                  ;set flags bit
  343. ;
  344. ;Below, determine if user had entered the abbreviation for a cleared
  345. ;flag (e.g. user entered "NC").  If so, clear the bit
  346.  
  347.                 
  348.                 cmp     bx, flags_info_mid               
  349.                 jb      short accept_f100
  350.                 btr     ax, dx                  ;clear flags bit
  351.                 jmp     short accept_f100
  352. accept_f800:
  353.                 clc
  354.                 ret                      
  355. accept_f900:
  356.                 stc
  357.                 ret
  358. accept_flags    endp        
  359.  
  360. show_regs       proc    near
  361.                 xor     dx, dx                  ;register counter
  362.                 mov     si, offset regs_indx
  363.  
  364. show_r100:
  365.                 push    si                      ;entry in table of indices
  366.                 xor     bh, bh
  367.                 mov     bl, [si]                ;offset of register to display
  368.                 cmp     dx, NUM_REGS_DISP - 1
  369.                 je      short show_r205
  370. ;
  371. ;get start of text string for register
  372.                 mov     si, [bx + regs_info_start].regs_text_off 
  373.                 sub     ch, ch
  374.                 mov     cl, [bx + regs_info_start].regs_text_len        
  375. show_r200:
  376.                 call    disp_reg_eq
  377. show_r205:
  378. ;
  379. ;get offset on stack where register is located
  380.                 mov     si, [bx + regs_info_start].regs_stack_off
  381.                 mov     ax,  [bp + si]          ;get register value
  382.                 cmp     dx, NUM_REGS_DISP - 1   ;are we on flags?
  383.                 jne     short show_r250         ;if not, go do regular reg
  384. ;
  385. ;Display flags register values
  386. ;
  387.                 call    disp_reg_flags
  388.                 jmp     short show_r330
  389.  
  390. show_r250:
  391.                 call    disp_reg_val
  392. show_r330:
  393.  
  394.                 pop     si
  395.                 inc     si                      ;advance to next register
  396.                 inc     dx                      ;count one we just did
  397.                 cmp     dx, NUM_REGS_1LINE
  398.                 jne     short show_r400
  399.                 call    scroll_cmds_up
  400.                 
  401. show_r400:
  402.                 cmp     dx, NUM_REGS_DISP
  403.                 jb      short show_r100
  404.                 call    scroll_cmds_up
  405.  
  406.                 ret
  407. show_regs       endp
  408.  
  409.  
  410.  
  411. ;----------------------------------------------------------------------
  412. ;disp_reg_flags - display textual descriptions of flags               |
  413. ;                 register values.                                    |
  414. ;                                                                     |
  415. ;               Enter:    ax = flags register contents                |
  416. ;                      es:di = destination in video buffer            |
  417. ;                Exit:    di adjusted                                 |
  418. ;                         bx, dx saved                                |
  419. ;----------------------------------------------------------------------
  420. disp_reg_flags  proc    near
  421.                 push    bx
  422.                 push    dx
  423.                 mov     bx, offset flags_info_start
  424.                 mov     cx, FLAGS_ALL_BITS 
  425. disp_rf210:
  426.                 mov     dl, [bx].fbit           ;bit number in flags reg
  427.                 mov     si, [bx].ftext_off      ;offset of bit description
  428.                 push    cx
  429.                 sub     ch, ch
  430.                 mov     cl, [bx].flen           ;length of description
  431. disp_rf215:
  432.                 sub     dh, dh
  433.                 bt      ax, dx                  ;is bit set in flags?
  434.                 jc      short disp_rf220        ;if so, go move text
  435. ;else advance to text for bits not set
  436.                 add     si, SET_FLAGS_LEN
  437. disp_rf220:
  438.                 movsb                           ;move desription to display
  439.                 inc     di                      ;skip attribute byte
  440.                 loop    disp_rf220
  441.                 pop     cx
  442.                 add     di, 2                   ;next display position
  443.                 add     bx, size flags_tbl
  444.                 loop    disp_rf210
  445.                 pop     dx
  446.                 pop     bx
  447.                 ret
  448. disp_reg_flags  endp
  449.  
  450.  
  451. ;--------------------------------------------------------------
  452. ;disp_reg_eq - display textual description of register and    |
  453. ;              follow it with an equals sign.                 |
  454. ;                                                             |
  455. ;               Enter: ds:si = description text.              |
  456. ;                         cx = length of description          |
  457. ;                      es:di = destination in video buffer    |
  458. ;                Exit:    di, si, cx adjusted                 |
  459. ;                                                             |
  460. ;         ax saved                                            |
  461. ;--------------------------------------------------------------
  462. disp_reg_eq     proc    near
  463.                 push    ax
  464. disp_re100:
  465.                 movsb                           ;move text to display
  466.                 inc     di                      ;past video attribute
  467.                 loop    disp_re100
  468.                 mov     al, '='                 ;equal sign
  469.                 stosb
  470.                 inc     di
  471.                 pop     ax
  472.                 ret
  473. disp_reg_eq     endp
  474.  
  475.  
  476.  
  477. ;--------------------------------------------------------------
  478. ;disp_reg_val - display register value and follow it with     |
  479. ;               a couple of spaces.                           |
  480. ;                                                             |
  481. ;               Enter:    ax = register value                 |
  482. ;                      es:di = destination in video buffer    |
  483. ;                Exit:    di adjusted                         |
  484. ;                                                             |
  485. ;   DX Saved.                                                 |
  486. ;--------------------------------------------------------------
  487. disp_reg_val    proc    near
  488.                 push    dx
  489.                 call    put_hex_word
  490.                 pop     dx
  491.                 mov     al, ' '
  492.                 mov     cx, 2                   ;skip 2 spaces after register
  493. disp_reg_v100:
  494.                 stosb
  495.                 inc     di                      
  496.                 loop    disp_reg_v100
  497.                 ret
  498. disp_reg_val    endp
  499.  
  500.  
  501.  
  502. do_dump         proc    near
  503.                 mov     dx, BYTES_TO_DUMP       ;load default number of bytes        
  504.                 call    skip_white_sp
  505.                 or      cx, cx
  506.                 jnz     short do_d150  
  507.  
  508. do_d100:
  509. ;
  510. ;only 'd' with nothing else.  If dumped before, start with last dump
  511. ;address else use ds:0
  512.                 cmp     did_dump, TRUE  ;have dumped before?
  513.                 je      short do_d800
  514.  
  515. do_d150:
  516.                 push    dx                      ;save default bytes to dump
  517.                 mov     dx, [bp].regs_ds        ;default to ds:0 for dump
  518.                 mov     dump_address.d_seg, dx ;store seg    
  519.                 xor     bx, bx                  ;zero offset
  520.                 mov     dump_address.d_offset, bx ;store offset 
  521.                 pop     dx                      ;restore bytes to dump
  522.  
  523.                 jcxz    do_d800                 ;if only d and no previous d
  524.  
  525. do_d200:
  526.                 assume  ds:data
  527.                 call    get_seg_off             ;get seg:off in dx:bx
  528.                 jnc     short do_d300           ;if not invalid
  529. do_d280:
  530.                 mov     si, offset bad_addrs_msg
  531. do_d285:
  532.                 call    prt_err_msg             ;print msg and set carry 
  533.                 ret                  
  534. do_d300:
  535.  
  536.                 cmp     seg_found, TRUE         ;segment found?
  537.                 jne     short do_d350
  538.                 mov     dump_address.d_seg, dx  ;store it
  539. do_d350:
  540.                 mov     dump_address.d_offset, bx  ;store offset
  541.  
  542. do_d500:                                        ;look for range
  543.                 mov     dx, BYTES_TO_DUMP       ;default # bytes to dump
  544.                 call    skip_white_sp
  545.                 jcxz    do_d800
  546.                 mov     dx, 4                   ;inspect a max of 4 digits
  547.                 call get_validate               ;go get one
  548.                 mov     si, offset bad_range_msg
  549.                 jc      short do_d285           ;if it was invalid, exit
  550.                 mov     dx, 10h                 ;if illegal range, do 10h
  551.                 cmp     dump_address.d_offset, ax ;must be > offset
  552.                 ja      short do_d800
  553.                 mov     dx, ax                  ;"to" portion of range
  554.                 sub     dx, dump_address.d_offset ;minus offset
  555. do_d800:
  556.                 push    ds                      ;save our data segment
  557.                   
  558.                 lds     si, dump_address        ;get starting address
  559.                 assume  ds:nothing
  560. ;ready to dump        
  561.                 call    dump_n_count
  562.                 pop     ds
  563.                 assume  ds:data
  564.                 mov     did_dump, TRUE          ;indicate did dump  
  565.                 add     dump_address.d_offset, dx ;pick up here next dump
  566.  
  567. do_d999:
  568.                 stc                             ;stay in debug cmd loop
  569.                 ret
  570. do_dump         endp
  571.  
  572.  
  573.  
  574. do_edit_b       proc    near
  575.                 mov     edit_length, 1          ;edit bytes
  576.                 mov     edit_num, 16            ;16 of them
  577.                 call    do_edit
  578.                 ret
  579. do_edit_b       endp
  580.  
  581.  
  582.  
  583. do_edit         proc    near
  584.                 call    skip_white_sp
  585.                 jcxz    short do_e280  
  586.                 mov     dx, [bp].regs_ds        ;default to ds for edit seg
  587.                 push    dx
  588.                 call    get_seg_off             ;get seg:off in dx:bx
  589.                 pop     ax                      ;restore default segment
  590.                 jnc     short do_e300           ;if not invalid
  591. do_e280:
  592.                 mov     si, offset bad_addrs_msg
  593.                 jmp     short do_e380
  594. do_e300:
  595.  
  596.                 cmp     seg_found, TRUE         ;segment found?
  597.                 je      short do_e350
  598.                 mov     dx, ax                  ;if not, use ds
  599. do_e350:
  600.                 call    skip_white_sp
  601.                 jcxz    do_e400
  602.                 mov     si, offset syntax_msg
  603. do_e380:
  604.                 call    prt_err_msg             ;print msg and set carry 
  605.                 ret                  
  606. do_e400:
  607.                 mov     edit_address.d_seg, dx
  608.                 mov     gs, dx                  ;save seg here too
  609.                 mov     edit_address.d_offset, bx  ;save edit address
  610.  
  611. do_e425:
  612.                 push    ds                      ;save our data segment
  613.                 lds     si, edit_address
  614.                 assume  ds:nothing
  615.                 call    dump_a_line             ;display the data
  616.                 pop     ds
  617.                 assume  ds:data    
  618.                 mov     dl, edit_length         ;length of each item to edit
  619.                 movzx   cx, edit_num            ;number of them
  620.                 mov     si, offset cmd_buffer
  621.                 call    get_dump                ;get formatted data to buffer
  622.                 mov     get_out, SPACE_KEY      ;exit on this and cr and esc
  623.                 mov     ax, offset must_be_hex 
  624.                 mov     edit_routine, ax        ;editing routine for hex
  625. ;
  626. ;ds:si=edit buffer, es:di=start of edit area in video
  627. ;dl=max number of nibbles to get
  628. do_e450:
  629.                 xor     bx, bx                  ;init char counter
  630.                 mov     dh, dl                  ;init max gone = number to get
  631.                 push    di                      ;save starting cursor position
  632.                 call    editor
  633.                 pop     di                      ;restore start cursor position
  634.                 sub     dh, dh                  
  635.                 add     di, dx                  ;advance past chars
  636.                 add     di, dx                  ;and attributes
  637.                 add     di, 2                   ;past space between  
  638.                 push    ax                      ;save get out key
  639.                 push    cx                      ;save number of edit items
  640.                 movzx   cx, dl                  ;max digits to get
  641.                 xor     ax, ax                  ;default to zero
  642.                 call    skip_white_sp
  643.                 jcxz    do_e490
  644.                 call    convert_upper
  645.                 call    get_validate
  646. do_e490:                                    
  647.                 pop     cx                       
  648.                 inc     si
  649.                 mov     bx, edit_address.d_offset
  650.                 cmp     edit_length, 1          ;editing bytes?
  651.                 jne     short do_e500
  652.                 mov     gs:[bx], al
  653.                 jmp     short do_e600
  654. do_e500:                                    
  655.                 mov     gs:[bx], ax
  656.                 inc     bx                    
  657. do_e600:                                    
  658.                 inc     bx
  659.                 mov     edit_address.d_offset, bx  ;save edit offset
  660.                 
  661.                 pop     ax                      ;get out key
  662.                 cmp     al, ESC_KEY
  663.                 je      short do_e700
  664.                 loop    do_e450
  665.                 call    scroll_cmds_up
  666.                 jmp     short do_e425
  667.  
  668. do_e700:
  669.                 call    scroll_cmds_up
  670. do_e999:
  671.                 stc                             ;stay in debug cmd loop
  672.                 ret
  673. do_edit         endp
  674.  
  675. ;--------------------------------------------------------------
  676. ;get_dump - Get data ready for editing.  Data has been        |
  677. ;           formatted and placed in the video buffer in the   |
  678. ;           dump format.  Get the formatted data and move it  |
  679. ;           into the edit work buffer.  Also, position the    |
  680. ;           pointers to the start of the data for display and |
  681. ;           editing.                                          |
  682. ;                                                             |
  683. ;               Enter:                                        |
  684. ;                         si = offset edit work buffer.       |
  685. ;                         dl = length of data items in bytes  |
  686. ;                         cx = number of data items           |
  687. ;                                                             |
  688. ;                                                             |
  689. ;                Exit:    dl = length of data items in nibbles|
  690. ;                         di = offset of start of dump data   |
  691. ;                              (past seg:offset)              |
  692. ;                                                             |
  693. ;    cx, si saved                                             |
  694. ;--------------------------------------------------------------
  695. get_dump        proc    near
  696.                 push    cx
  697.                 push    si
  698.                 mov     di, wrk_vid_offset      ;get prompt location
  699.                 add     di, 24          ;get past prompt and "xxxx:xxxx  "
  700.                 push    di              ;save this spot
  701.                 shl     dl, 1           ;get number of digits
  702. get_d100:
  703.                 xor     bl, bl
  704. get_d200:
  705.                 mov     al, es:[di]     ;get formatted data from video buf
  706.                 mov     [si],al         ;move into work buffer
  707.                 add     di, 2           ;next data in video buffer
  708.                 inc     si              ;next work buffer position
  709.                 inc     bl
  710.                 cmp     bl, dl
  711.                 jne     short get_d200
  712.                 mov     byte ptr [si], ' ' ;space between data items
  713.                 inc     si
  714.                 add     di, 2
  715.                 loop    get_d100
  716.                 pop     di
  717.                 pop     si
  718.                 pop     cx
  719.                 ret
  720. get_dump        endp        
  721.  
  722. ;--------------------------------------------------------------
  723. ;get_seg_off - Search cmd buffer for seg:off specified as     |
  724. ;              registers or hex or both.                      |
  725. ;                                                             |
  726. ;               Enter:    si = offset of cmd buffer           |
  727. ;                         cx = remaining chars in buffer      |
  728. ;                         bp = base of stack area where user  |
  729. ;                              regs have been stored.         |
  730. ;                                                             |
  731. ;                Exit:    si and cx adjusted                  |
  732. ;                         gs = segment specified (if any)     |
  733. ;                         dx = segment specified (if any)     |
  734. ;                  seg_found = TRUE if segment specified      |
  735. ;                         bx = offset                         |
  736. ;                                                             |
  737. ;                         carry set if invalid address        |
  738. ;                                                             |
  739. ;   No registers saved                                        |
  740. ;--------------------------------------------------------------
  741. get_seg_off     proc    near
  742.                 mov     seg_found, FALSE        ;no segment found yet
  743.                 push    cx                      ;save number of chars entered
  744.                 mov     cx, REGS_SEGS_ENTRIES   ;number of seg registers
  745.                 mov     bx, regs_info_segs      ;start of seg register info
  746.                 mov     ax, size regs_stab      ;size to inc when search
  747.                 call    str_lookup
  748.                 or      cx, cx
  749.                 pop     cx
  750.                 jz      short get_s300          ;if no seg register found
  751.                 sub     cl, [bx].regs_text_len  ;subtract length of reg text
  752.  
  753.                 push    si                      ;save cmd line offset
  754.                 
  755.                 mov     si, [bx].regs_stack_off ;offset on stack for reg
  756.                 mov     ax, [bp + si]           ;get register value
  757.                 mov     gs, ax                  ;store it
  758.                 mov     seg_found, TRUE         ;indicate we found it
  759.                 pop     si
  760.                 call    skip_white_sp
  761.                 xor     bx, bx                  ;default to zero offset 
  762.                 jcxz    get_s800                ;if no more chars on cmd line
  763.  
  764. get_s100:                                       ;look for ':'
  765.                 cmp     byte ptr [si], ':' 
  766.                 je      short get_s290
  767. get_s200:
  768.                 stc                             
  769.                 jmp     get_s999
  770. get_s290:
  771.                 inc     si                      ;past the ":"
  772.                 call    skip_white_sp
  773.                 jcxz    get_s200                ;if ':' was last thing
  774. get_s300:                                                        
  775. ;look for registers used to specify offset for dump
  776.                 push    cx                     ;save number of chars entered
  777.                 mov     cx, REGS_GEN_ENTRIES   ;number of nonseg registers
  778.                 mov     bx, offset regs_info_start ;start of register info
  779.                 mov     ax, size regs_stab      ;size to inc when search
  780.                 call    str_lookup
  781.                 or      cx, cx
  782.                 pop     cx
  783.                 jz      short get_s400          ;if no registers found
  784.                 sub     cl, [bx].regs_text_len  ;subtract length of reg text
  785.  
  786.                 push    si
  787. ;check for sp or bp
  788.                 cmp     bx, offset regs_info_sp ;sp register?
  789.                 je      short get_s350
  790.                 cmp     bx, offset regs_info_bp ;bp register?
  791.                 jne     short get_s380
  792. get_s350:                                       ;if sp or bp
  793.                 cmp     seg_found, TRUE         ;and no segment specified
  794.                 je      short get_s380
  795.                 mov     ax, [bp].regs_ss        ;use stack segment       
  796.                 mov     gs, ax                  ;store it
  797.                 mov     seg_found, TRUE         ;seg "found" (bp, sp use ss)
  798. get_s380:
  799.                 mov     si, [bx].regs_stack_off ;offset on stack for reg
  800.                 mov     bx, [bp + si]           ;get register value
  801.                 pop     si
  802.                 jmp     short get_s800          ;and exit            
  803. get_s400:                                        ;look for hex number
  804.                 mov     dx, 4                   ;inspect a max of 4 digits
  805.                 cmp     seg_found, TRUE         ;segment specified yet?
  806.                 je      short get_s425
  807.                 mov     dh, ':'                 ;may hit before 4 digits
  808. get_s425:
  809.                 call get_validate               ;go get one
  810.                 jc      short get_s999          ;if invalid, exit with carry
  811.                 cmp     seg_found, TRUE         ;segment specified yet?
  812.                 je      short get_s450
  813.                 call    skip_white_sp           ;anthing else?
  814.                 jcxz    get_s450                 ;if not, it was just offset
  815.  
  816.                                                 ;look for ':'
  817.                 cmp     byte ptr [si], ':'
  818.                 jne     short get_s450
  819.  
  820.                 mov     gs, ax                  ;store it
  821.                 mov     seg_found, TRUE         ;segment found
  822.                 jmp     short get_s290          ;go look for offset
  823. get_s450:
  824.                 mov     bx, ax                  ;return offset in bx
  825. get_s800:
  826.                 mov     dx, gs                  ;and segment in dx
  827.                 clc
  828. get_s999:
  829.                 ret
  830. get_seg_off     endp        
  831.  
  832. do_quit         proc    near
  833.                 clc                     ;indicate exit debugger
  834.                 ret
  835. do_quit         endp
  836.  
  837. ;--------------------------------------------------------------
  838. ; do_xud- Process eXit to User Debugger commmand.  Look for   |
  839. ;         int number.  If specified, validate it.  If not     |
  840. ;         specified, use int specified in last XUD command.   |
  841. ;         If command was never previously issued and no int   |
  842. ;         is specified, use DEF_UD_INT.                       |
  843. ;                                                             |
  844. ;           Enter: si = offset of cmd buffer just after "XUD" |
  845. ;                  cx = max chars entered - cmd length        |
  846. ;                                                             |
  847. ;            Exit: If invalid Carry set                       |
  848. ;                  else Carry clear indicating exit debugger  |
  849. ;                  and                                        |
  850. ;                  cs:xudflag=TRUE                            |
  851. ;                   cs:xud_ip=Offset of ISR for user debug int|
  852. ;                   cs:xud_cs=segment of same                 |
  853. ;                  cs:xud_int=int specifed                    |
  854. ;--------------------------------------------------------------
  855. do_xud          proc    near
  856.                 call    skip_white_sp
  857.                 jcxz    do_xud090       ;no int number specified 
  858.                 mov     dx, 2           ;get max of 2 digits, dh=0
  859.                 call    get_validate    ;return value in ax
  860.                 jnc     short do_xud070
  861. do_xud050:
  862.                 mov     si, offset bad_int_msg
  863.                 call    prt_err_msg             ;print msg and set carry 
  864.                 ret
  865. do_xud070:
  866.                 mov     bx, ax          ;get specified int number
  867.                 mov     cs:xud_int, al  ;save it for next time
  868.                 jmp     short do_xud500
  869. do_xud090:
  870.                 sub     bh, bh
  871.                 mov     bl, cs:xud_int
  872.                 or      bl, bl                  ;xud done before?
  873.                 jnz     short do_xud500         ;if so, use last int specified
  874. ;and go get cs:ip of isr again (it may have changed)
  875. ;
  876.                 mov     bx, DEF_UD_INT          ;else use default
  877. do_xud500:
  878.                 push    ds
  879.                 xor     ax, ax
  880.                 mov     ds, ax                  
  881.                 shl     bx, 2                   ;get vector entry
  882.                 mov     ax, [bx].d_offset       
  883.                 mov     cs:xud_ip, ax
  884.                 mov     ax, [bx].d_seg   
  885.                 mov     cs:xud_cs, ax
  886.                 pop     ds
  887. do_xud900:
  888.                 mov     xudflag, TRUE           ;indicate process XUD
  889.                 clc                             ;indicate exit debugger
  890. do_xud999:
  891.                 ret
  892. do_xud          endp
  893.  
  894. do_bc           proc    near
  895.                 call    skip_white_sp
  896.                 jcxz    short do_bc900          ;error, no arguments      
  897.                 mov     al, [si]                ;get first byte of arg
  898.                 cmp     al, '*'                 ;clear all break points?
  899.                 jne     short do_bc100
  900.                 cmp     num_used, 0             ;any to clear?
  901.                 je      short do_bc999          ;if not, ignore command
  902.  
  903.                 call    clear_all_bp
  904.                 jmp     short do_bc999
  905. do_bc100:
  906.                 mov     dx, 2                   ;get max of 2 digits, dh=0
  907.                 call    get_validate            ;return value in ax
  908.                 jc      short do_bc900
  909.                 call    skip_white_sp
  910.                 or      cx, cx                  ;any remaining chars in arg?
  911.                 jnz     short do_bc900          ;if so, they don't belong
  912.                 movzx   dx, max_goneto
  913.                 mov     si, offset bad_bc_msg2  ;number exceeded max msg
  914.                 cmp     ax, dx                  ;is number > max      
  915.                 jae     short do_bc950          ;if so, error
  916.                 call    clear_bp
  917.                 jmp     short do_bc999
  918. do_bc900:
  919.                 mov     si, offset bad_bc_msg1
  920. do_bc950:
  921.                 call    prt_err_msg
  922. do_bc999:
  923.                 stc                             ;stay in debug
  924.                 ret
  925. do_bc           endp
  926.  
  927. clear_all_bp    proc    near
  928.                 sub     al, al                  ;start with first break point
  929. clear_all100:
  930.                 call    clear_bp
  931.                 inc     al                      ;advance to next break point
  932.                 cmp     al, max_goneto
  933.                 jne     short clear_all100
  934.                 ret
  935. clear_all_bp    endp
  936.  
  937. ;--------------------------------------------------------------
  938. ;clear_bp - Clear break point.  Clear the break point in the  |
  939. ;           master break point list.  Also, clear it in the   |
  940. ;           detailed list (i.e. individual lists for break    |
  941. ;           point register type, interrupt type, or I/O type  |
  942. ;           break points).  Decrement the counters for the    |
  943. ;           total number of break points and individual       |
  944. ;           number for the break point type.                  |
  945. ;                                                             |
  946. ;               Enter:    al = break point number to be       |
  947. ;                              cleared.  It is guaranteed to  |
  948. ;                              be a valid existing break      |
  949. ;                              point.                         |
  950. ;                                                             |
  951. ;   AX saved.                                                 |
  952. ;--------------------------------------------------------------
  953. clear_bp        proc    near
  954.                 push    ax
  955.                 mov     bx, offset brk_list     ;get start of master list
  956.                 mov     dl, size mast_list
  957.                 mul     dl                      ;break point * entry size
  958.                 add     bx, ax                  ;gives offset into master list
  959.  
  960.                 cmp     [bx].brk_type, AVAIL    ;if already clear
  961.                 je      short clear_bp999
  962.                 dec     num_used                ;number total breakpoints - 1
  963.                 cmp     [bx].brk_type, DEB_TYPE_INT ;type being cleared int?
  964.                 ja      short   clear_bp200     ;if i/o type break point
  965.                 je      short   clear_bp100     ;if int type break point
  966.                 dec     num_reg_type            ;debug reg type breaks - 1
  967. ;
  968. ;Break point being cleared is a debug register type.  If it is a data
  969. ;access type break point (vs execution type), decrement count of data
  970. ;type break points.  Also, if this is the last debug register data access
  971. ;break point, clear the ge bit in the debug control register.
  972. ;
  973.                 push    bx
  974.                 mov     bx, [bx].brk_off        ;get offset of detailed list
  975.                 cmp     [bx].info_bptype, DEB_TYPE_EXEC ;exec type ?
  976.                 pop     bx
  977.                 je      short clear_bp300
  978.                 dec     num_reg_data            ;dec # data byte break points
  979.                 jnz     short clear_bp300
  980.  
  981. ;
  982. ;Clear ge bit when last data access type break point is removed.
  983. ;
  984.                 mov     cx, 1                   ;indicate clear/reg 1     
  985.                 mov     ax, ge_bit              ;clear ge bit
  986.                 int     60h                     ;do_debug_reg
  987.                 jmp     short clear_bp300
  988. clear_bp100:
  989.                 dec     num_int_bp              ;int type breaks - 1
  990.                 jmp     short clear_bp300
  991. clear_bp200:
  992.                 dec     num_io_bp               ;io type breaks - 1
  993. clear_bp300:
  994.                 mov     [bx].brk_type, AVAIL    ;make available in master list
  995.                 mov     bx, [bx].brk_off        ;get offset of detailed list
  996. ;
  997. ;Status is first byte in each entry in all lists.
  998. ;
  999.                 mov     byte ptr [bx], AVAIL    ;make available in detailed lists
  1000. clear_bp999:
  1001.                 pop     ax
  1002.                 ret
  1003. clear_bp        endp
  1004.  
  1005.  
  1006.  
  1007. ;--------------------------------------------------------------
  1008. ; do_bl - Break point list command.  Search break point       |
  1009. ;         master list and display all active break points.    |
  1010. ;                                                             |
  1011. ;              Enter: max_goneto = highest break point number |
  1012. ;                                  that has ever been defined.|
  1013. ;                                                             |
  1014. ;                                                             |
  1015. ;--------------------------------------------------------------
  1016. do_bl           proc    near
  1017.                 sub     al, al
  1018.                 mov     bx, offset brk_list
  1019. do_bl100:
  1020.                 cmp     [bx].brk_type, AVAIL    ;is break point active
  1021.                 je      short do_bl510          ;if not, go get next one
  1022.  
  1023.                 push    ax
  1024.                 push    bx
  1025.  
  1026.                 call    put_nibble              ;display number in al
  1027.                 mov     al, ')'                 ;followed by ') '
  1028.                 stosb
  1029.                 add     di, 3                   ;attribute, space, attribute
  1030.  
  1031.                 cmp     [bx].brk_type, DEB_TYPE_INT ;what type of break point?
  1032.                 ja      short do_bl350          ;above is I/O type
  1033.                 je      short do_bl300          ;int type            
  1034.                 call    disp_deb_reg            ;debug reg type
  1035.                 jmp     short do_bl400
  1036. do_bl300: 
  1037.                 call    disp_int_bp
  1038.                 jmp     short do_bl400
  1039. do_bl350: 
  1040.                 call    disp_io_bp
  1041. do_bl400: 
  1042.                 call    scroll_cmds_up
  1043. do_bl500:
  1044.                 pop     bx
  1045.                 pop     ax
  1046. do_bl510:
  1047.                 add     bx, size mast_list
  1048.                 inc     al
  1049.                 cmp     al, max_goneto
  1050.                 jb      short do_bl100
  1051.                 stc                             ;stay in debugger
  1052.                 ret
  1053. do_bl           endp
  1054.  
  1055. disp_int_bp     proc    near
  1056.                 mov     si, offset brk_pint
  1057.                 mov     cx,  BRK_PINT_LEN
  1058. disp_int100:
  1059.                 movsb
  1060.                 inc     di              ;past attribute
  1061.                 loop    disp_int100
  1062.                 add     di, 2           ;skip a space
  1063.                 mov     bx, [bx].brk_off ;offset of int list entry      
  1064.                 mov     al, [bx].int_num        ;get int number
  1065.                 call    put_hex_byte     ;display it          
  1066.                 add     di, 2           ;skip a space
  1067. ;
  1068. ;See if ax was specified as a condition
  1069. ;
  1070.                 mov     al, [bx].int_reg ;none, al, ah, or ax
  1071.                 or      al, al          ;none?
  1072.                 jz      disp_int999     ;if so, done
  1073.                 mov     cx, REGS16_TEXT_LEN
  1074.                 mov     si, offset ax_text
  1075.                 cmp     al, INT_AH_COMP
  1076.                 ja      short disp_int500
  1077.                 mov     si, offset ah_text
  1078.                 je      short disp_int500
  1079.                 mov     si, offset al_text
  1080.  
  1081. disp_int500:
  1082.                 pushf                   ;save flags per compare on reg type
  1083. disp_int510:
  1084.                 movsb                   ;put out register name
  1085.                 inc     di              ;past attribute
  1086.                 loop    disp_int510
  1087.                 mov     al, '='
  1088.                 stosb
  1089.                 inc     di              ;past attribute
  1090.                 mov     ax, [bx].int_val
  1091.                 popf
  1092.                 ja      short disp_int600 ;if ax
  1093.                 call    put_hex_byte     
  1094.                 jmp     short disp_int999
  1095. disp_int600:
  1096.                 call    put_hex_word
  1097. disp_int999:
  1098.                 ret
  1099. disp_int_bp     endp        
  1100.  
  1101. disp_io_bp      proc    near
  1102.                 mov     si, offset brk_pio 
  1103.                 mov     cx,  BRK_PIO_LEN
  1104. disp_io100:
  1105.                 movsb
  1106.                 inc     di                      ;past attribute
  1107.                 loop    disp_io100
  1108.                 add     di, 2                   ;skip a space
  1109.                 mov     bx, [bx].brk_off        ;offset of int list entry      
  1110.  
  1111.                 mov     ax, [bx].io_port        ;get port value 
  1112.                 call    put_hex_word            ;display it          
  1113.                 add     di, 2                   ;skip a space
  1114.  
  1115.                 mov     al, [bx].io_dir ;get indicator of port direction
  1116.                 mov     bx, offset dir_indic_r ;decriptions and indicators
  1117.                 mov     cx, DIR_TABLE_ENTRIES 
  1118. disp_io200:
  1119.                 cmp     [bx].text_code, al      ;find entry for it?
  1120.                 je      short disp_io400        ;if so, go get text
  1121.                 add     bx, size off_len_code
  1122.                 loop    disp_io200
  1123. disp_io400:
  1124.                 mov     si, [bx].text_off  ;get description of port direction
  1125.                 movzx   cx, [bx].text_len
  1126. disp_io500:
  1127.                 movsb                   ;display it             
  1128.                 inc     di              ;past attribute
  1129.                 loop    disp_io500
  1130. disp_io999:
  1131.                 ret
  1132. disp_io_bp      endp        
  1133.  
  1134. disp_deb_reg    proc    near
  1135.                 mov     bx, [bx].brk_off        ;offset of detailed debug info
  1136.                 mov     si, [bx].info_bpcmd     ;offset of data for this cmd
  1137.                 movzx   cx, [si].cmd_len 
  1138.                 mov     si, [si].cmd_text
  1139. disp_deb100:
  1140.                 movsb
  1141.                 inc     di              ;past attribute
  1142.                 loop    disp_deb100
  1143.                 add     di, 2           ;skip a space
  1144.                 push    ds
  1145.                 lds     si, dword ptr [bx].info_bpoff ;get address
  1146.                 call    format_seg      ;go display it
  1147.                 add     di, 2           ;skip a space
  1148.                 pop     ds
  1149. ;
  1150. ;Next, if break point is for data accesses, print a description of
  1151. ;the type of access (i.e. "W" or "RW")
  1152. ;
  1153.                 mov     si, offset write_text ;default to write
  1154.                 mov     cx, WRITE_LEN
  1155.                 mov     dl, [bx].info_bptype 
  1156.                 cmp     dl, DEB_TYPE_WRITE 
  1157.                 jb      short disp_deb900 ;if execution type, no direction
  1158.                 je      short disp_deb500
  1159.                 mov     si, offset rw_text ;r/w description
  1160.                 mov     cx, RW_LEN
  1161.  
  1162. disp_deb500:
  1163.                 movsb
  1164.                 inc     di
  1165.                 loop    disp_deb500
  1166. disp_deb900:
  1167.                 ret
  1168. disp_deb_reg    endp
  1169.  
  1170.  
  1171.  
  1172. do_bp           proc    near
  1173.                 mov     al, DEB_DAT_LEN1 
  1174.                 call    do_data_brk
  1175.                 ret
  1176. do_bp           endp
  1177.  
  1178. do_bpw          proc    near
  1179.                 mov     al, DEB_DAT_LEN2 
  1180.                 call    do_data_brk
  1181.                 ret
  1182. do_bpw          endp        
  1183.  
  1184. do_bpd          proc    near
  1185.                 mov     al, DEB_DAT_LEN4 
  1186.                 call    do_data_brk
  1187.                 ret
  1188. do_bpd          endp
  1189.  
  1190.  
  1191.  
  1192. do_bpx          proc    near
  1193.                 mov     fs, bx          ;save offset where command found
  1194.                 call    skip_white_sp
  1195.                 jcxz    do_bpx050       ;must specify address
  1196.                 call    get_seg_off     ;go get bpx address
  1197.                 jnc     short do_bpx100
  1198. do_bpx050:
  1199.                 mov     si, offset bad_addrs_msg
  1200.                 call    prt_err_msg             ;print msg and set carry 
  1201.                 ret                    
  1202. do_bpx100:
  1203.                 cmp     seg_found, TRUE ;user specify a segment?
  1204.                 je      short do_bpx200
  1205.                 mov     dx, [bp].regs_cs        ;get user cs register
  1206. do_bpx200:
  1207.                 call    check_max_deb           
  1208.                 jc      short do_bpx999
  1209.                 call    check_max_bps
  1210.                 jc      short do_bpx999
  1211.  
  1212. ;have bpx address in dx:bx
  1213.                 push    di
  1214.                 mov     cx, MAX_BRK_POINTS      ;number in list
  1215.                 mov     ax, size mast_list
  1216.                 mov     si, offset brk_list
  1217.                 call    get_and_mark            ;find spot in master list
  1218. ;si=offset of entry in master list
  1219.                 mov     di, si                  ;save in di
  1220.                  
  1221.                 mov     si, offset bp_reg_dat   ;debug registers list
  1222.                 mov     ax, size info_bpreg     ;size of entries in list
  1223.                 mov     cx, MAX_DR_BRK_POINTS   ;number in list
  1224.                 call    get_and_mark            ;find spot and assign
  1225. ;exec breaks use 1 byte length
  1226.                 mov     ax, ( (DEB_TYPE_EXEC shl 8) OR DEB_DAT_LEN1 )
  1227.                 call    add_to_master           ;add to master list
  1228.                 call    add_db_list
  1229.                 pop     di
  1230.                 inc     cl                      ;debug reg # = entry # + 1
  1231.  
  1232.                 call    convert_2_linear        ;dx:bx to linear in edx
  1233.                 mov     ch, 2                   ;setup debug register
  1234.                 int     60h                     ;do_debug_reg
  1235. do_bpx999:
  1236.                 stc                     ;stay in debug cmd loop
  1237.                 ret
  1238. do_bpx          endp
  1239.  
  1240.  
  1241. ;--------------------------------------------------------------
  1242. ; do_data_brk - Process BP, BPB, BPW and BPD commands.        |
  1243. ;               Validate command parameters.  If invalid,     |
  1244. ;               print error message else load appropriate     |
  1245. ;               data structures and debug register.           |
  1246. ;                                                             |
  1247. ;               Enter: al = length code for debug register    |
  1248. ;                      bx = offset in command table where the |
  1249. ;                           command (i.e. "BP", "BPB", "BPW", |
  1250. ;                           or "BPD" was found).              |
  1251. ;                                                             |
  1252. ;                Exit: carry set.                             |
  1253. ;                                                             |
  1254. ;--------------------------------------------------------------
  1255. do_data_brk     proc    near
  1256.                 mov     fs, bx          ;save offset where command found
  1257.                 call    skip_white_sp
  1258.                 jcxz    do_data_b050    ;must specify address
  1259.                 push    ax              ;save length code
  1260.                 call    get_seg_off     ;go get break point address
  1261.                 pop     ax              ;restore length code
  1262.                 jnc     short do_data_b100
  1263. do_data_b050:
  1264.                 mov     si, offset bad_addrs_msg
  1265. do_data_b070:
  1266.                 call    prt_err_msg             ;print msg and set carry 
  1267.                 ret                       
  1268. do_data_b100:
  1269.                 cmp     seg_found, TRUE ;user specify a segment?
  1270.                 je      short do_data_b200
  1271.                 mov     dx, [bp].regs_ds        ;get user ds register
  1272. do_data_b200:
  1273. ;have bp address in dx:bx
  1274.                 mov     ah, DEB_TYPE_RW         ;default to r/w
  1275.                 call    skip_white_sp
  1276.                 jcxz    do_data_b300
  1277.                 
  1278.                 push    bx
  1279.  
  1280.                 push    ax
  1281.                 mov     cx, RW_W_ENTRIES         ;number of ("rw", "w")
  1282.                 mov     bx, offset dir_indic_rw  ;table of text
  1283.                 mov     ax, size off_len_code    ;size to inc when search
  1284.                 call    str_lookup
  1285.                 pop     ax
  1286.                 mov     ah, [bx].text_code      ;get type code 
  1287.  
  1288.                 pop     bx
  1289.  
  1290.                 or      cx, cx                  
  1291.                 jnz     short do_data_b300      ;if user input was valid
  1292. ;
  1293. ;was expecting "W" or "RW" and didn't get either
  1294. ;
  1295.                 mov     si, offset bad_bp_msg
  1296.                 jmp     short do_data_b070
  1297. do_data_b300:
  1298.                 call    check_max_deb 
  1299.                 jc      short do_data_b1000
  1300.                 call    check_max_bps
  1301.                 jc      short do_data_b1000
  1302.                 push    di
  1303.                 push    ax                      ;save type and length
  1304.                 mov     cx, MAX_BRK_POINTS      ;number in list
  1305.                 mov     ax, size mast_list
  1306.                 mov     si, offset brk_list
  1307.                 call    get_and_mark            ;find spot in master list
  1308. ;si=offset of entry in master list
  1309.                 mov     di, si                  ;put it in di
  1310.                 mov     si, offset bp_reg_dat   ;debug registers list
  1311.                 mov     ax, size info_bpreg     ;size of entries in list
  1312.                 mov     cx, MAX_DR_BRK_POINTS   ;number in list
  1313.                 call    get_and_mark            ;find spot and assign
  1314.  
  1315.                 pop     ax                      ;restore type and length
  1316.  
  1317.                 call    add_to_master           ;add to master list
  1318.                 call    add_db_list
  1319.                 inc     num_reg_data            ;# data type break points
  1320.                 pop     di
  1321.                 inc     cl                      ;debug reg # = entry # + 1
  1322.                 call    convert_2_linear        ;dx:bx to linear in edx
  1323.                 mov     ch, 2                   ;setup debug register
  1324.                 int     60h                     ;do_debug_reg
  1325. do_data_b999:
  1326.                 stc                             ;stay in debug cmd loop
  1327. do_data_b1000:
  1328.                 ret
  1329. do_data_brk     endp
  1330.  
  1331. ;--------------------------------------------------------------
  1332. ; get_and_mark - Find first available entry in list of break  |
  1333. ;                points.  Mark the entry as active.  All      |
  1334. ;                structures processed with this routine must  |
  1335. ;                have the status field at the same offset.    |
  1336. ;                                                             |
  1337. ;                There will always be an available entry      |
  1338. ;                found as callers check this first.           |
  1339. ;                                                             |
  1340. ;                This is currently called when processing the |
  1341. ;                lists of:  debug register type break points, |
  1342. ;                int break points, and I/O break points.  It  |
  1343. ;                is also used to find available entries in    |
  1344. ;                the master break point list.                 |
  1345. ;                                                             |
  1346. ;                                                             |
  1347. ;               Enter: si = offset of break point list        |
  1348. ;                      ax = amount by which to increment table|
  1349. ;                           index.                            |
  1350. ;                      cx = number of items in table          |
  1351. ;                                                             |
  1352. ;                Exit: si = offset where first available      |
  1353. ;                           entry found.                      |
  1354. ;                                                             |
  1355. ;                      cx = entry number where found.         |
  1356. ;                                                             |
  1357. ;    DX saved.                                                |
  1358. ;                                                             |
  1359. ;--------------------------------------------------------------
  1360. get_and_mark    proc    near
  1361.                 push    dx
  1362.                 mov     dx, cx          ;save number of entries        
  1363. get_and_m100:
  1364.                 cmp     [si].info_bpstat, AVAIL
  1365.                 je      short get_and_m200
  1366.                 add     si, ax          ;increment to next entry
  1367.                 loop    get_and_m100
  1368. get_and_m200:
  1369.                 mov     [si].info_bpstat, ACTIVE ;flag as being used
  1370.                 sub     dx, cx          ;compute entry number
  1371.                 mov     cx, dx
  1372.                 pop     dx
  1373.                 ret
  1374. get_and_mark    endp        
  1375.  
  1376. ;--------------------------------------------------------------
  1377. ; add_db_list - Fill in an entry in the list of debug register|
  1378. ;               type break points.  Also, flag the status as  |
  1379. ;               "temporarily disabled" so that the break point|
  1380. ;               will be enabled in the debug register when    |
  1381. ;               debugger is exited.                           |
  1382. ;                                                             |
  1383. ;               Enter: si = offset for this entry in list of  |
  1384. ;                           debug register type break points. |
  1385. ;                      al = length (0=byte, 1=word, 3=dword)  |
  1386. ;                      ah = type (0=exec, 1=write, 3=r/w)     |
  1387. ;                   dx:bx = address for break point           |
  1388. ;                                                             |
  1389. ;                       fs = offset of entry in command table |
  1390. ;                            where command was found.  This   |
  1391. ;                            is stored so that a description  |
  1392. ;                            of the command can be easily     |
  1393. ;                            produced when listing break      |
  1394. ;                            points via the "BL" command.     |
  1395. ;                                                             |
  1396. ;                                                             |
  1397. ;--------------------------------------------------------------
  1398. add_db_list     proc    near
  1399.                 or      [si].info_bpstat, DEB_TEMP_DISAB
  1400.                 mov     [si].info_bpoff, bx
  1401.                 mov     [si].info_bpseg, dx
  1402.                 mov     [si].info_bpsize, al
  1403.                 mov     [si].info_bptype, ah
  1404.                 mov     [si].info_bpcmd, fs
  1405.                 ret
  1406. add_db_list     endp        
  1407.  
  1408. ;--------------------------------------------------------------
  1409. ; add_int_list - Fill in an entry in the list of interrupt    |
  1410. ;               type break points.  Also, add to num_int_bp.  |
  1411. ;                                                             |
  1412. ;               Enter: si = offset for this entry in list of  |
  1413. ;                           interrupt type break points.      |
  1414. ;                                                             |
  1415. ;                      dh = interrupt number                  |
  1416. ;                                                             |
  1417. ;                      dl = indication of type of compare on  |
  1418. ;                           ax (0=no compare, 1=compare on al,|
  1419. ;                               2=compare on ah, 3=compare on |
  1420. ;                               ax)                           |
  1421. ;                                                             |
  1422. ;                      ax = compare value                     |
  1423. ;                                                             |
  1424. ;                Exit:  num_int_bp is incremented.            |
  1425. ;                                                             |
  1426. ;--------------------------------------------------------------
  1427. add_int_list    proc    near
  1428.                 mov     [si].int_stat, ACTIVE
  1429.                 mov     [si].int_num, dh
  1430.                 mov     [si].int_reg, dl
  1431.                 mov     [si].int_val, ax
  1432.                 inc     num_int_bp              ;inc int break point count
  1433.                 ret
  1434. add_int_list    endp
  1435.  
  1436. ;--------------------------------------------------------------
  1437. ; add_io_list - Fill in an entry in the list of I/O           |
  1438. ;               type break points.  Also, add to num_io_bp.   |
  1439. ;                                                             |
  1440. ;               Enter: si = offset for this entry in list of  |
  1441. ;                           I/O type break points.            |
  1442. ;                                                             |
  1443. ;                      dx = I/O port address                  |
  1444. ;                                                             |
  1445. ;                      al = code indicating "R", "RW" or "W"  |
  1446. ;                                                             |
  1447. ;                Exit:  num_io_bp is incremented.             |
  1448. ;                                                             |
  1449. ;--------------------------------------------------------------
  1450. add_io_list     proc    near
  1451.                 mov     [si].io_port, dx
  1452.                 mov     [si].io_dir, al
  1453.                 inc     num_io_bp               ;inc I/O break point count
  1454.                 ret
  1455. add_io_list     endp
  1456.  
  1457.  
  1458. ;--------------------------------------------------------------
  1459. ; add_to_master - Fill in an entry in master list of all      |
  1460. ;                 break points.  Also, advance count of       |
  1461. ;                 maximum break points ever defined in this   |
  1462. ;                 session if necessary.                       |
  1463. ;                                                             |
  1464. ;               Enter: di = offset for this entry in master   |
  1465. ;                           list of break points.             |
  1466. ;                      ah = type of break point being assigned|
  1467. ;                           to this entry (0=exec, 1=write    |
  1468. ;                           2=unused, 3=r/w, 4=int, 5=i/o)    |
  1469. ;                      si = offset of entry in list of        |
  1470. ;                           information regarding the         |
  1471. ;                           type of break point (the entry    |
  1472. ;                           in the table of debug register    |
  1473. ;                           type break points, int type and   |
  1474. ;                           I/O type)                         |
  1475. ;                                                             |
  1476. ;      ax saved                                               |
  1477. ;--------------------------------------------------------------
  1478. add_to_master   proc    near
  1479.                 push    ax
  1480.                 mov     [di].brk_type, ah       ;type of break point
  1481.                 mov     [di].brk_off, si        ;entry in break table
  1482.                 mov     al, num_used            ;number of active breaks
  1483. ;Compare with maximum break points ever defined in this session. (i.e. more
  1484. ;may have existed before this, but user may have cleared them).  This is
  1485. ;maintained because when break points are cleared, the list is not 
  1486. ;compressed (e.g. if you have 3 break points and delete the 2nd one, you 
  1487. ;will still reference your active break points as #1 and #3).
  1488. ;
  1489.                 cmp     al, max_goneto                                
  1490.                 jbe     short add_to_m999
  1491.                 inc     max_goneto
  1492. add_to_m999:
  1493.                 pop     ax
  1494.                 ret                           
  1495. add_to_master   endp        
  1496.  
  1497.  
  1498. do_bpio         proc    near
  1499.                 call    skip_white_sp
  1500.                 jcxz    do_bpio050      ;must specify i/o port   
  1501.                 mov     dx, 4           ;get a max of 4 digits
  1502.                 call    get_validate    ;return value in ax
  1503.                 jnc     short do_bpio100 ;if port valid, continue
  1504. do_bpio050:
  1505.                 mov     si, offset bad_io_msg              
  1506. do_bpio070:
  1507.                 call    prt_err_msg             ;print msg and set carry 
  1508.                 ret                     
  1509. do_bpio100:
  1510.                 mov     dx, ax                  ;hold port address
  1511.                 mov     al, DEB_TYPE_RW         ;default to r/w
  1512.                 call    skip_white_sp
  1513.                 jcxz    do_bpio300
  1514.                 
  1515.  
  1516.                 push    ax
  1517.                 mov     cx, DIR_TABLE_ENTRIES    ;number of ("r", "rw", "w")
  1518.                 mov     bx, offset dir_indic_r   ;table of text
  1519.                 mov     ax, size off_len_code    ;size to inc when search
  1520.                 call    str_lookup
  1521.                 pop     ax
  1522.                 mov     al, [bx].text_code      ;get type code 
  1523.  
  1524.                 or      cx, cx                  
  1525.                 jnz     short do_bpio300      ;if user input was valid
  1526. ;
  1527. ;was expecting "W", "RW" or "R" and didn't get any of these
  1528. ;
  1529.                 mov     si, offset bad_iodir_msg          
  1530.                 jmp     short do_bpio070
  1531. do_bpio300:
  1532.                 call    check_max_bps 
  1533.                 jc      short do_bpio1000
  1534.                 push    ax                      ;save type
  1535.                 mov     cx, MAX_BRK_POINTS      ;number in list
  1536.                 mov     ax, size mast_list
  1537.                 mov     si, offset brk_list
  1538.                 call    get_and_mark            ;find spot in master list
  1539. ;si=offset of entry in master list
  1540.                 mov     di, si                  ;put it in di
  1541.                 mov     si, offset io_bpdat     ;i/o break point list
  1542.                 mov     ax, size info_io        ;size of entries in list
  1543.                 mov     cx, MAX_BRK_POINTS      ;number in list
  1544.                 call    get_and_mark            ;find spot and assign
  1545.  
  1546.                 pop     ax                      ;restore type
  1547.  
  1548.                 call    add_io_list
  1549.                 mov     ah, DEB_TYPE_IO         ;indicate I/O type break point
  1550.                 call    add_to_master           ;add to master list
  1551. do_bpio999:
  1552.                 stc                     ;stay in debug cmd loop
  1553. do_bpio1000:
  1554.                 ret
  1555. do_bpio         endp        
  1556.  
  1557. do_bpint        proc    near
  1558.                 call    skip_white_sp
  1559.                 jcxz    do_bpi050       ;must specify int number
  1560.                 mov     dx, 2           ;get max of 2 digits, dh=0
  1561.                 call    get_validate    ;return value in ax
  1562.                 mov     dh, al          ;save interrupt number in dh
  1563.                 jnc     short do_bpi100
  1564. do_bpi050:
  1565.                 mov     si, offset bad_int_msg
  1566.                 jmp     short do_bpi410
  1567. do_bpi100:
  1568.                 mov     dl, NO_CONDITION        ;default to no more args
  1569.                 xor     ax, ax                  ;with no compare value        
  1570.                 call    skip_white_sp
  1571.                 jcxz    short do_bpi500
  1572.  
  1573.                 push    cx                      ;save count chars in cmd
  1574.                 mov     cx, AX_TABLE_ENTRIES    ;3 (al, ah, and ax)
  1575.                 mov     bx, offset tab_ax       ;table of text for al, ah, ax
  1576.                 mov     ax, size off_len_code    ;size to inc when search
  1577.                 call    str_lookup
  1578.                 or      cx, cx
  1579.                 pop     cx
  1580.                 jz      short do_bpi400           ;jmp if error
  1581. ;
  1582. ;Found al, ah, or ax.  Now, store indication of this and look for "EQ" or "="
  1583. ;
  1584.                 call    skip_white_sp
  1585.                 jcxz    short do_bpi400
  1586.                 push    cx
  1587.                 mov     dl, [bx].text_code      ;get al, ah, ax code 
  1588.                 mov     cx, EQ_TABLE_ENTRIES    ;2 ("=" and "EQ")
  1589.                 mov     bx, offset operators    ;table of "=" and "EQ"
  1590.                 mov     ax, size off_len_code    ;size to inc when search
  1591.                 call    str_lookup
  1592.                 or      cx, cx
  1593.                 pop     cx
  1594.                 jz      short do_bpi400         ;jmp if error
  1595.  
  1596.                 call    skip_white_sp
  1597.                 jcxz    short do_bpi400
  1598.                 push    dx                      ;save int number/ax code
  1599.                 mov     al, dl
  1600.                 mov     dx, 2                   ;number of digits in byte reg        
  1601.                 cmp     al, INT_AX_COMP         ;doing word reg?
  1602.                 jne     short do_bpi200
  1603.                 shl     dx, 1                   ;number of digits in word reg
  1604. do_bpi200:
  1605.                 call    get_validate            ;return value in ax
  1606.                 pop     dx                      
  1607.                 jnc     short do_bpi500
  1608.  
  1609. do_bpi400:
  1610.                 mov     si, offset syntax_msg   ;error    
  1611. do_bpi410:
  1612.                 call    prt_err_msg             ;print msg and set carry 
  1613.                 ret                                          
  1614.  
  1615. do_bpi500:
  1616.                 call    check_max_bps           ;see if break point > max  
  1617.                 jc      short do_bpi999         ;if so, reject it
  1618.  
  1619.                 push    ax                      ;save compare value
  1620.                 push    dx                      ;save ax type
  1621.  
  1622.                 mov     cx, MAX_BRK_POINTS      ;number in list
  1623.                 mov     ax, size mast_list
  1624.                 mov     si, offset brk_list
  1625.                 call    get_and_mark            ;find spot in master list
  1626. ;si=offset of entry in master list
  1627.                 mov     di, si                  ;save in di
  1628.                  
  1629.                 mov     si, offset int_bpdat    ;int break point list
  1630.                 mov     ax, size info_int       ;size of entries in list
  1631.                 mov     cx, MAX_BRK_POINTS      ;number in list
  1632.                 call    get_and_mark            ;find spot and assign
  1633.                 pop     dx                      ;restore ax type
  1634.                 pop     ax                      ;and ax compare value
  1635.                 call    add_int_list            ;put info in int list
  1636.                 mov     ah, DEB_TYPE_INT        ;indicate int type break point
  1637.                 call    add_to_master           ;put into master list
  1638. do_bpi999:
  1639.                 stc                             ;stay in debug cmd loop
  1640.  
  1641.                 ret
  1642. do_bpint        endp        
  1643.  
  1644. check_max_bps   proc    near
  1645.                 cmp     num_used, MAX_BRK_POINTS
  1646.                 jb      short check_m100
  1647.                 mov     si, offset max_bps_msg
  1648.                 call    prt_err_msg             ;print msg and set carry 
  1649.                 ret                     
  1650. check_m100:
  1651.                 inc     num_used
  1652.                 clc
  1653.                 ret
  1654. check_max_bps   endp
  1655.  
  1656.  
  1657. check_max_deb   proc    near
  1658. ;
  1659. ;Logic could also be added here to prevent duplicate break points from being
  1660. ;defined.
  1661. ;
  1662.                 cmp     num_reg_type, MAX_DR_BRK_POINTS 
  1663.                 jb      short check_mdb100
  1664.                 mov     si, offset max_deb_msg            
  1665.                 call    prt_err_msg             ;print msg and set carry 
  1666.                 ret                                            
  1667. check_mdb100:
  1668.                 inc     num_reg_type
  1669.                 clc
  1670.                 ret
  1671. check_max_deb   endp
  1672.  
  1673. ;--------------------------------------------------------------
  1674. ;dump_n_count - do a dump of specified area.                  |
  1675. ;                                                             |
  1676. ;               Enter: ds:si = ptr to area.                   |
  1677. ;                         dx = number of bytes.               |
  1678. ;                Exit:    dx saved.                           |
  1679. ;--------------------------------------------------------------
  1680. dump_n_count    proc    near
  1681.                 push    dx
  1682. dump_n_c100:
  1683.                 call    dump_a_line
  1684.  
  1685.                 push    ds
  1686.                 mov     ax, DATA
  1687.                 mov     ds, ax
  1688.                 call    scroll_cmds_up
  1689.                 pop     ds
  1690.  
  1691.                 cmp     dx, 10h
  1692.                 jbe     short dump_n_c200
  1693.                 sub     dx, 10h
  1694.                 jmp     short dump_n_c100            
  1695. dump_n_c200:
  1696.                 pop     dx
  1697.                 ret
  1698. dump_n_count    endp
  1699.  
  1700.  
  1701. ;--------------------------------------------------------------
  1702. ;dump_a_line - given a ptr ds:si to a buffer, put 10h bytes   |
  1703. ;              of dump data into video buffer at es:di.       |
  1704. ;--------------------------------------------------------------
  1705. dump_a_line     proc    near
  1706.                 push    dx
  1707.                 push    di                      ;save start print buf
  1708.                 call    format_seg
  1709.                 add     di,4                    ;skip 2 spaces
  1710.                 mov     cx, 10h
  1711.                 push    si                      ;save start of data
  1712. dump_a_l100:
  1713.                 lodsb
  1714.                 call    put_hex_byte             ;print hex
  1715.                 cmp     cl, 9
  1716.                 jne     short dump_a_l200
  1717.                 mov     al, '-'
  1718.                 mov     es:[di],al
  1719. dump_a_l200:
  1720.                 add     di, 2
  1721.                 loop    dump_a_l100
  1722.                 pop     si
  1723.                 add     di, 4                   ;skip 2 spaces
  1724.                 mov     cx, 10h
  1725. dump_a_l250:
  1726.                 lodsb
  1727.                 cmp     al, ' '
  1728.                 jae     short dump_a_l300
  1729.                 mov     al, '.'
  1730. dump_a_l300:
  1731.                 stosb                           ;print ASCII
  1732.                 inc     di                      ;past attribute
  1733.                 loop    dump_a_l250        
  1734.  
  1735.                 pop     di
  1736.                 pop     dx
  1737.                 ret
  1738. dump_a_line     endp
  1739.  
  1740. zcode           ends
  1741.             end     
  1742.  
  1743.